package net.stratusprogramming.school.Game.Framework.Items;

import java.text.DecimalFormat;
import net.stratusprogramming.school.Game.Framework.Battle.Combatant;

/**
 * A that allows an item (potion, weapon, etc.) to affect a combatant
 * 
 * @author Dominic Vitello, Patrick Lienau
 * @version 0.1
 * @since 5/8/12
 */
public class Effect {

	/** Determines if defense will be taken into account */
	private boolean isAttack;
	
	/** Change in health */
	private float health;
	/** Change in mana */
	private float mana;
	/** Change in defense */
	private float defense;	
	
	/** Percent of subtracted health to add to affecter */
	private float percentHealthLeached;
	/** Percent of subtracted mana to add to affecter */
	private float percentManaLeached;
	/** Percent of subtracted defense to add to affecter */
	private float percentDefenseLeached;

	/** To format string representation of effect */
	private static final DecimalFormat dmt = new DecimalFormat("0.##");
	
	/**
	 * Creates an effect that also has an effector
	 * 
	 * @param if attack take defense into account
	 */
	public Effect(boolean isAttack) {
		this.isAttack = isAttack;
	}
	

	/**
	 * Applies the effect to affected
	 *  
	 * @param affected the combatant that is affected
	 * @return A string representation what happened to display in battle log  [0] is affected, [1] is affecter
	 */
	public String affect(Combatant affected) {
		return affect(affected, null);
	}
	
	/**
	 * Applies the effect to affected and possibly the affecter
	 *  
	 * @param affected the combatant that is affected
	 * @param effecter the combatant that is affecting the affected
	 * @return A string representation what happened to display in battle log  [0] is affected, [1] is affecter
	 */
	public String affect(Combatant affected, Combatant affecter) {
		String ret = "";
		
		float deltaHealth = 0.0f, deltaMana = 0.0f, deltaDefense = 0.0f;
		
		// affect affected
		if(health != 0) {
			deltaHealth = health;
			if(isAttack) deltaHealth -= deltaHealth*affected.getDefense();		
			affected.setHealth(affected.getHealth()+deltaHealth);
			ret += " HP "+((deltaHealth > 0)?"+":"")+dmt.format(deltaHealth);
		}
		if(mana != 0) {
			deltaMana = mana;
			if(isAttack) deltaMana -= deltaMana*affected.getDefense();
			affected.setMana(affected.getMana()+deltaMana);
			ret += " MP "+((deltaMana > 0)?"+":"")+dmt.format(health);
		}
		if(defense != 0) {
			deltaDefense = defense;
			if(isAttack) deltaDefense -= deltaDefense*affected.getDefense();
			affected.setDefense(affected.getDefense()+defense);
			ret += " DEF "+((deltaDefense > 0)?"+":"")+dmt.format(health);
		}
		
		// affect affecter?
		if(affecter != null) {			
			if(percentHealthLeached != 0) {
				float delta = percentHealthLeached*deltaHealth*-1;
				affecter.setHealth(affecter.getHealth()+delta);
				ret += " HP leached "+dmt.format(delta);
			}
			if(percentManaLeached != 0) {
				float delta = percentManaLeached*deltaMana*-1;
				affecter.setMana(affecter.getMana()+delta);
				ret += " MP leached "+dmt.format(delta);
			}
			if(percentDefenseLeached != 0) {
				float delta = percentDefenseLeached*deltaDefense*-1;
				affecter.setDefense(affecter.getDefense()+delta);
				ret += " DEF leached "+dmt.format(delta);
			}
		}
		
		return ret;
	}	

	/**
	 * @return the isAttack
	 */
	public boolean isAttack() {
		return isAttack;
	}
	/**
	 * @param isAttack the isAttack to set
	 */
	public void setAttack(boolean isAttack) {
		this.isAttack = isAttack;
	}
	/**
	 * @return the health
	 */
	public float getHealth() {
		return health;
	}
	/**
	 * @param health the health to set
	 */
	public void setHealth(float health) {
		this.health = health;
	}
	/**
	 * @return the mana
	 */
	public float getMana() {
		return mana;
	}
	/**
	 * @param mana the mana to set
	 */
	public void setMana(float mana) {
		this.mana = mana;
	}
	/**
	 * @return the defense
	 */
	public float getDefense() {
		return defense;
	}
	/**
	 * @param defence the defense to set
	 */
	public void setDefense(float defense) {
		this.defense = defense;
	}
	/**
	 * @return the percentHealthLeached
	 */
	public float getPercentHealthLeached() {
		return percentHealthLeached;
	}
	/**
	 * @param percentHealthLeached the percentHealthLeached to set
	 */
	public void setPercentHealthLeached(float percentHealthLeached) {
		this.percentHealthLeached = percentHealthLeached;
	}
	/**
	 * @return the percentManaLeached
	 */
	public float getPercentManaLeached() {
		return percentManaLeached;
	}
	/**
	 * @param percentManaLeached the percentManaLeached to set
	 */
	public void setPercentManaLeached(float percentManaLeached) {
		this.percentManaLeached = percentManaLeached;
	}
	/**
	 * @return the percentDefenseLeached
	 */
	public float getPercentDefenseLeached() {
		return percentDefenseLeached;
	}
	/**
	 * @param percentDefenseLeached the percentDefenseLeached to set
	 */
	public void setPercentDefenseLeached(float percentDefenseLeached) {
		this.percentDefenseLeached = percentDefenseLeached;
	}	
}
